{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e7e19e44",
   "metadata": {},
   "source": [
    "# 元组"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b387a2b",
   "metadata": {},
   "source": [
    "## 基本操作"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f9d2a64",
   "metadata": {},
   "source": [
    "与列表类似，元组是一个有序序列，但是不可变。\n",
    "\n",
    "元组用小括号`()`生成："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "35ee8cf4",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = (10, 11, 12, 13, 14)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c84434ff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10, 11, 12, 13, 14)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "adeda902",
   "metadata": {},
   "source": [
    "可以索引，切片："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "af7e51ec",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0f0426de",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(11, 12)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t[1:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50e2275b",
   "metadata": {},
   "source": [
    "元组是不可变的，不能通过赋值改变："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "979e1f96",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [5]\u001b[0m, in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m t[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n",
      "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "t[0] = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1625a74f",
   "metadata": {},
   "source": [
    "## 单元素的元组生成\n",
    "\n",
    "由于()在表达式中被应用，只含有单个元素的元组容易和表达式混淆，所以采用下列方式定义只有一个元素的元组："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ca547219",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "71eb0d2b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "8866d98d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1a4e83a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (10,)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9c00526f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10,)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d8e52d8f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46100c0e",
   "metadata": {},
   "source": [
    "## 列表与元组的转换\n",
    "\n",
    "用构造方法`list`和`tuple`可以相互转换："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f7d0a973",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [10, 11, 12, 13, 14]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1a1c628d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10, 11, 12, 13, 14)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tuple(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "b53b3230",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (10, 11, 12, 13, 14)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c6d4da04",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 11, 12, 13, 14]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba4a8d6a",
   "metadata": {},
   "source": [
    "## 元组方法\n",
    "\n",
    "由于元组是不可变的，所以只能有一些不可变自身的方法，例如计算元素个数`.count()`方法和元素位置`.index()`方法，用法与列表一样："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d0962bc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = (10, 11, 12, 13, 14)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "04681a99",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.count(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "aa075db7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.index(12)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6ab6f06",
   "metadata": {},
   "source": [
    "## 列表与元组的速度比较\n",
    "\n",
    "IPython 中用 `magic` 命令 `%timeit` 来计时。\n",
    "\n",
    "比较列表与元组的生成速度："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "4f09ce16",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "108 ns ± 5.29 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n 100000 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0d7a5477",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12.7 ns ± 2.44 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n 100000 (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "459912da",
   "metadata": {},
   "source": [
    "在遍历上，元组和列表的速度表现差不多。\n",
    "\n",
    "产生内容相同的随机列表和元组："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "1fb682e4",
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy.random import rand\n",
    "\n",
    "values = rand(10000,4)\n",
    "\n",
    "lst = [list(row) for row in values]\n",
    "tup = tuple(tuple(row) for row in values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "e06d2883",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "719 µs ± 52.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n 100 for row in lst: tuple(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "5a8991fd",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "514 µs ± 29.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n 100 for row in tup: tuple(row)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5b49abc",
   "metadata": {},
   "source": [
    "比较遍历和索引速度："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "c41abaaf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.61 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit -n 100 for row in lst: a = row[0] + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "05d3a527",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.51 ms ± 88.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit for row in tup: a = row[0] + 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ae5c8dd",
   "metadata": {},
   "source": [
    "总结：元组的生成速度会比列表快很多，迭代速度快一点，索引速度差不多。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "4943884e",
   "metadata": {},
   "source": [
    "## 元组与多变量赋值\n",
    "\n",
    "Python支持多变量赋值的模式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "2ecf3911",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b = 1, 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "b43b3251",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "65c8cc66",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75df719f",
   "metadata": {},
   "source": [
    "Python中的多变量赋值，本质是两个元组中的元素进行一一对应，此时，等号两边的元素数目必须相等。例如，将包含两个元素的元组t的值分别赋给a和b："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "28a23af1",
   "metadata": {},
   "outputs": [],
   "source": [
    "t = (1, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "2cf6d0bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b = t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "a08094b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "9d72d41e",
   "metadata": {},
   "source": [
    "利用多变量赋值，变量的交换可以用一行代码实现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "8cb7c70b",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b = b, a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "db999b73",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "7cb8ac2d",
   "metadata": {},
   "source": [
    "多变量赋值支持超过两个值的操作，只要等号两边的元素数相同："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "aa5ebd4f",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b, c = 1, 2, 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a932b56",
   "metadata": {},
   "source": [
    "嵌套："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "5a2b3a03",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, (b, c) = 1, (2, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10e86d4a",
   "metadata": {},
   "source": [
    "带星号的赋值，将后面的值都变成一个列表给某个变量赋值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "589b4cc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, *b = 1, 2, 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "2a65ab3b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 3]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "734b13c4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "585bab96",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
